package main

import (
	"fmt"
	"reflect"
)

// 简单类型
func main() {
	//mySimple()
	myStruct()
}

func mySimple(){
	var x float64 = 3.4
	var z interface{} = &x // 保证interface 里面保存的是数据的指针
	p := reflect.ValueOf(z) // 注意这里：把x地址传进去了！
	//p := reflect.ValueOf(&x) // 注意这里：把x地址传进去了！
	fmt.Println(p.Type())   //*float64

	fmt.Println(p.CanSet()) //false 这里的p只是指针，仍然是non-settable的

	v := p.Elem() //此时的v保存了x

	fmt.Println(v.CanSet()) //true

	v.SetFloat(7.1)
	fmt.Println(v.Interface()) //7.1
	fmt.Println(x)             //7.1
}

func myStruct(){
	type T struct {
		A int `json:"a"`
		B string `json:"b"`
	}
	t := T{23, "skidoo"}
	s := reflect.ValueOf(&t).Elem()
	typeOfT := s.Type()//把s.Type()返回的Type对象复制给typeofT，typeofT也是一个反射。
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)//迭代s的各个域，注意每个域仍然是反射。
		fmt.Printf("%d: %s %s = %v %s  ===  \n", i,
			typeOfT.Field(i).Name, f.Type(), f.Interface(),typeOfT.Field(i).Tag)//提取了每个域的名字

	}
	//0: A int = 23
	//1: B string = skidoo

	s.Field(0).SetInt(77) //s.Field(0).Set(reflect.ValueOf(77))
	s.Field(1).SetString("Sunset Strip")
	fmt.Println("t is now", t)  //t is now {77 Sunset Strip}


	/*
	结构体分解为Value 和 Type 两个部分
		value 按结构顺序保存了内部的值
		type  按结构顺序保存了字段类型
	*/
}